package net.rlair.sbdemo.service;

import net.rlair.sbdemo.entity.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 使用Mybatis+默认连接池方式创建多个事务，设置隔离级别为read uncommitted，要求如下：
 * 1）模拟出现脏读的情况；
 * 2）代码放在service中，已IsolationLevel+开发姓名命名.
 * @author yaoyi
 */
@Service
public class IsolationLevelMainYaoyi {
    @Resource
    private IsolationLevelYaoyi isolationLevelYaoyi;

    /**
     * 解决脏读现象，需将事务级别设置为read_committed或其以上级别.
     */
    public void dirtyRead() {
        User user = isolationLevelYaoyi.addUser();
        //线程1：修改用户名，但发生异常
        Thread thread1 = new Thread(() -> {
            try {
                isolationLevelYaoyi.updateUserEx(user.getId());
            } catch (Exception e) {
                System.out.println(Thread.currentThread().getName() + "发生异常，事务回滚");
                e.printStackTrace();
            }
            //事务回滚后，查询用户,发现回滚失败
            User user2 = isolationLevelYaoyi.selectById(user.getId());
            System.out.println(Thread.currentThread().getName() + "---查看用户名:" + user2.getName());
            if (!user.getName().equals(user2.getName())) {
                System.out.println(Thread.currentThread().getName() + "事务回滚失败！");
            }
        });
        thread1.setName("线程1");
        thread1.start();
        //休息1s,保证事务正在执行中但还未回滚
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //线程2：出现脏读现象，并修改了数据
        Thread thread2 = new Thread(() -> {
            isolationLevelYaoyi.selectAndUpdate(user.getId());
        });
        thread2.setName("线程2");
        thread2.start();
    }
}
